using System;
using System.Collections.Generic;
using System.Diagnostics;
using InfiniTec.Data;

namespace InfiniTec.Expressions
{
    public class CompareExpression<T> : CompareExpressionBase<T>, ICompareExpression, IEnumExpression
    {  
        private CompareType _CompareType;

        public CompareType CompareType
        {
            [DebuggerStepThrough]
            get { return _CompareType; }
            [DebuggerStepThrough]
            set { _CompareType = value; }
        }


        object ICompareExpression.Value { get { return Value; } }


        IPropertyDefinition ICompareExpression.PropertyDefinition { get { return PropertyDefinition; } }

        CompareExpression<int> IEnumExpression.ToIntExpression()
        {
            if (!typeof(T).IsEnum) throw new NotSupportedException("This method is only permitted on enum expressions.");
            return new CompareExpression<int>(new PropertyDefinition<int>(PropertyDefinition.Name, PropertyDefinition.IsMultivalued), CompareType, Convert.ToInt32(Value));
        }

        public CompareExpression(PropertyDefinition<T> property, CompareType compareType, T value): base(property, value)
        {
            CompareType = compareType; 
        }

        #region IValueBasedExpression Members

//        IConvertible ICompareExpression.Value
//        {
//            get
//            {
//                IConvertible value = Value as IConvertible;
//
//                if (value == null) throw new NotSupportedException(
//                        string.Format(InfiniTec.Properties.Resources.SourceTypeDoesNotSupportIConvertible,
//                                      typeof(T).FullName));
//
//                return value;
//            }
//        }

        #endregion

        protected override bool Evaluate(T value, T actualValue)
        {
            int comparison;

            comparison = Comparer<T>.Default.Compare(actualValue, Value);

            switch(CompareType)
            {
                case Expressions.CompareType.Equals:
                    return (comparison == 0);
                case Expressions.CompareType.Greater:
                    return (comparison == 1);
                case Expressions.CompareType.GreaterOrEqual:
                    return (comparison >= 0);
                case Expressions.CompareType.NotEquals:
                    return (comparison != 0);
                case CompareType.Smaller:
                    return (comparison < 0);
                case Expressions.CompareType.SmallerOrEqual:
                    return (comparison <= 0);
            }

            return false;
        }
    }
}
